package com.chenfan.mcn.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.clients.privilege.PrivilegeClient;
import com.chenfan.mcn.clients.privilege.SUserVo;
import com.chenfan.mcn.constant.BillCodeCst;
import com.chenfan.mcn.constant.NumberCst;
import com.chenfan.mcn.dao.AeQuarterlyTableMapper;
import com.chenfan.mcn.dao.AeRoyaltiesMapper;
import com.chenfan.mcn.enums.*;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.component.CodeGenerateHelper;
import com.chenfan.mcn.model.AeQuarterlyTable;
import com.chenfan.mcn.model.AeRoyalties;
import com.chenfan.mcn.model.McnPage;
import com.chenfan.mcn.model.common.PageInfo;
import com.chenfan.mcn.model.dto.*;
import com.chenfan.mcn.model.vo.AeQuarterlyBoxList;
import com.chenfan.mcn.service.*;
import com.chenfan.mcn.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author chenguopeng
 * @Date 2021/6/7 15:56
 */
@Service
@Slf4j
public class AeQuarterlyTableServiceImpl extends ServiceImpl<AeQuarterlyTableMapper, AeQuarterlyTable>
        implements AeQuarterlyTableService {

    @Autowired
    private AeRoyaltiesService aeRoyaltiesService;

    @Resource
    private AeRoyaltiesMapper aeRoyaltiesMapper;

    @Autowired
    private PrivilegeClient privilegeClient;

    @Autowired
    private ContractExcutionOrderService contractExcutionOrderService;

    @Autowired
    private AeExcutorConfirmService aeExcutorConfirmService;

    @Resource
    private AeQuarterlyTableMapper aeQuarterlyTableMapper;


    /**
     * 发送人姓名
     */
    @Value("${send.default.username:钱昱帆}")
    private String sendName;

    @Override
    public PageInfo<AeQuarterlyTable> getPage(McnPage<AeQuarterlyTable> page, AeQuarterlyTableSearchDTO dto) {
        page.setPageSize(dto.getPageSize());
        page.setPageNum(dto.getPageNum());
        return PageInfo.toPageInfo(aeQuarterlyTableMapper.selectAeByPage(page, dto));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrUpdate(AeQuarterlyTableDTO aeQuarterlyTableDTO) {
        // id
        AeQuarterlyTable oldAeQuarterlyTable = null;
        if (aeQuarterlyTableDTO.getId() != null) {
            oldAeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeQuarterlyTableDTO.getId());
        }
        if (Objects.nonNull(oldAeQuarterlyTable)) {
            oldAeQuarterlyTable.setAeQuarterlyCode(aeQuarterlyTableDTO.getAeQuarterlyCode());
            oldAeQuarterlyTable.setRemark(aeQuarterlyTableDTO.getRemark());
            aeQuarterlyTableMapper.updateById(oldAeQuarterlyTable);
            aeQuarterlyTableDTO.setId(oldAeQuarterlyTable.getId());
            aeQuarterlyTableDTO.setStatus(oldAeQuarterlyTable.getStatus());
            aeQuarterlyTableDTO.setIsDelete(oldAeQuarterlyTable.getIsDelete());
        } else {
            AeQuarterlyTable aeQuarterlyTable = new AeQuarterlyTable();
            aeQuarterlyTable.setAeQuarterlyCode(aeQuarterlyTableDTO.getAeQuarterlyCode());
            aeQuarterlyTable.setAeQuarterlyExcuteCode(CodeGenerateHelper.getCode(BillCodeCst.AE_TCD_BASIC));
            aeQuarterlyTable.setStatus(AeQuarterlyTypeEnum.NEW_CONTRACT.getCode());
            aeQuarterlyTable.setRemark(aeQuarterlyTableDTO.getRemark());
            aeQuarterlyTable.setIsDelete(DataStatusEnum.NEW_CONTRACT.getCode());
            // 插入AE季度执行单
            aeQuarterlyTableMapper.insert(aeQuarterlyTable);
            aeQuarterlyTableDTO.setId(aeQuarterlyTable.getId());
            aeQuarterlyTableDTO.setStatus(aeQuarterlyTable.getStatus());
            aeQuarterlyTableDTO.setIsDelete(aeQuarterlyTable.getIsDelete());
        }
        // 插入执行单
        aeRoyaltiesService.create(aeQuarterlyTableDTO);
        return aeQuarterlyTableDTO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer update(AeQuarterlyTableUpdateDTO aeQuarterlyTableUpdateDTO) {
        AeQuarterlyTable aeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeQuarterlyTableUpdateDTO.getId());
        List<AeRoyalties> list = aeRoyaltiesMapper.selectList(
                Wrappers.lambdaQuery(AeRoyalties.class).eq(AeRoyalties::getAeQuarterlyId, aeQuarterlyTable.getId())
                        .eq(AeRoyalties::getIsDelete, DataStatusEnum.ZC_CONTRACT.getCode()));
        List<Long> executeIds = list.stream().map(AeRoyalties::getExcuteId).collect(Collectors.toList());
        List<String> isRepeatExecuteIds = aeRoyaltiesMapper.checkIsRepeats(aeQuarterlyTableUpdateDTO.getId());
        if (!CollectionUtils.isEmpty(isRepeatExecuteIds)) {
            throw new BusinessException(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.code(),
                    String.format(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.message(), CommonUtil.listToString(isRepeatExecuteIds, ',')));
        }
        isRepeatExecuteIds = aeRoyaltiesMapper.checkIsRepeat(executeIds, aeQuarterlyTable.getId());
        if (!CollectionUtils.isEmpty(isRepeatExecuteIds)) {
            throw new BusinessException(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.code(),
                    String.format(McnErrorCode.AE_EXCUTE_CANNOT_BE_REPEATED.message(), CommonUtil.listToString(isRepeatExecuteIds, ',')));
        }
        //新建状态下
        if (DataStatusEnum.NEW_CONTRACT.getCode() == aeQuarterlyTable.getIsDelete()) {
            // 执行单改为已结算
            batchUpdateSettleStatus(executeIds, CommonSettleStatusEnum.IN_SETTLEMENT.code());
        }
        AeQuarterlyTable updateEntity = new AeQuarterlyTable();
        updateEntity.setId(aeQuarterlyTable.getId());
        updateEntity.setIsDelete(DataStatusEnum.ZC_CONTRACT.getCode());
        updateEntity.setRemark(aeQuarterlyTableUpdateDTO.getRemark());
        updateEntity.setAeQuarterlyCode(aeQuarterlyTableUpdateDTO.getAeQuarterlyCode());
        aeQuarterlyTableMapper.updateById(updateEntity);

        List<AeRoyalties> commissionDetails = list.stream()
                .filter(CommonUtil.distinctByKey(AeRoyalties::getExcutorId)).collect(Collectors.toList());
        List<AeRoyalties> departmentDetails = list.stream()
                .filter(s -> Objects.nonNull(s.getDepPrincipalNameId()))
                .filter(CommonUtil.distinctByKey(AeRoyalties::getDepPrincipalNameId)).collect(Collectors.toList());
        aeExcutorConfirmService.batchCreate(new AeExcutorConfirmNewDTO(aeQuarterlyTable.getId(),
                commissionDetails.stream().map(AeRoyalties::getExcutorId).collect(Collectors.toList()),
                AeCommonEnum.IS_EXCUTOR.getCode()));
        aeExcutorConfirmService.batchCreate(new AeExcutorConfirmNewDTO(aeQuarterlyTable.getId(),
                departmentDetails.stream().map(AeRoyalties::getDepPrincipalNameId).collect(Collectors.toList()),
                AeCommonEnum.IS_DEPPRINCIPALNAMEID.getCode()));
        return NumberCst.ZERO;
    }

    /**
     * 修改状态
     *
     * @param aeRoyaltiesExportDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeStatus(AeRoyaltiesExportDTO aeRoyaltiesExportDTO) {
        AeQuarterlyTable aeQuarterlyTable = aeQuarterlyTableMapper.selectById(aeRoyaltiesExportDTO.getAeQuarterlyId());
        Integer aeQuarterlyType = aeRoyaltiesExportDTO.getStatus();
        List<AeRoyalties> aeRoyaltiesList = aeRoyaltiesMapper.popUsList(aeRoyaltiesExportDTO);
        if (aeQuarterlyTable.getStatus().equals(AeQuarterlyTypeEnum.YZF_CONTRACT.getCode())) {
            throw new BusinessException(McnErrorCode.AE_INVALID);
        }
        List<Long> excuteIds = aeRoyaltiesList.stream().map(AeRoyalties::getExcuteId).collect(Collectors.toList());
//        List<AeRoyalties> commissionDetails = aeRoyaltiesList.stream()
//                .filter(CommonUtil.distinctByKey(AeRoyalties::getExcutorId)).collect(Collectors.toList());
//        List<AeRoyalties> departmentDetails = aeRoyaltiesList.stream()
//                .filter(s -> Objects.nonNull(s.getDepPrincipalNameId()))
//                .filter(CommonUtil.distinctByKey(AeRoyalties::getDepPrincipalNameId)).collect(Collectors.toList());
        // 发送提成单
//        String aeQuarterlyCode = CommonUtil.getAeQuarterlyCode(aeQuarterlyTable.getAeQuarterlyCode());
        //v2.1版本 取消发送逻辑
        // if (aeQuarterlyType.equals(AeQuarterlyTypeEnum.YFS_CONTRACT.getCode())) {
        //     if (aeRoyaltiesList.size() < 1) {
        //         throw new BusinessException(McnErrorCode.AE_DETAIL_IS_NULL);
        //     }
        //     if (Objects.isNull(aeRoyaltiesExportDTO.getType())) {
        //         commissionDetails
        //                 .forEach(x -> approvalFlowService.sendAeNotify(aeQuarterlyTable.getTenantId(),
        //                         aeQuarterlyTable.getId(), aeQuarterlyTable.getAeQuarterlyExcuteCode(),
        //                         aeQuarterlyCode, ApprovalEnum.AE_COMMISSION, true, x.getExcutorId(),
        //                         x.getExcutorName(), AeCommonEnum.IS_EXCUTOR.getCode()));
        //         departmentDetails
        //                 .forEach(x -> approvalFlowService.sendAeNotify(aeQuarterlyTable.getTenantId(),
        //                         aeQuarterlyTable.getId(), aeQuarterlyTable.getAeQuarterlyExcuteCode(),
        //                         aeQuarterlyCode, ApprovalEnum.AE_DEPARTMENT, true,
        //                         x.getDepPrincipalNameId(), x.getDepPrincipalName(),
        //                         AeCommonEnum.IS_DEPPRINCIPALNAMEID.getCode()));
        //     }
        // }
        // 确认提成单 v2.1版本 取消确认逻辑
        // if (aeQuarterlyType.equals(AeQuarterlyTypeEnum.YQR_CONTRACT.getCode())) {
        //     if (AeCommonEnum.IS_EXCUTOR.getCode().equals(aeRoyaltiesExportDTO.getType())) {
        //         aeExcutorConfirmService
        //                 .update(new AeExcutorConfirmNewDTO(aeQuarterlyTable.getId(), AeCommonEnum.IS_EXCUTOR.getCode(),
        //                         AeCommonEnum.IS_CONFIRM.getCode(), aeRoyaltiesExportDTO.getExcutorId()));
        //     }
        //     if (AeCommonEnum.IS_DEPPRINCIPALNAMEID.getCode().equals(aeRoyaltiesExportDTO.getType())) {
        //         aeExcutorConfirmService.update(
        //                 new AeExcutorConfirmNewDTO(aeQuarterlyTable.getId(), AeCommonEnum.IS_DEPPRINCIPALNAMEID.getCode(),
        //                         AeCommonEnum.IS_CONFIRM.getCode(), aeRoyaltiesExportDTO.getExcutorId()));
        //     }
        //     if (Objects.isNull(aeRoyaltiesExportDTO.getType())) {
        //         aeExcutorConfirmService.update(new AeExcutorConfirmNewDTO(aeQuarterlyTable.getId(), null,
        //                 AeCommonEnum.IS_CONFIRM.getCode(), null));
        //     }
        //
        // }
        // 已发放提成单
        if (aeQuarterlyType.equals(AeQuarterlyTypeEnum.YFF_CONTRACT.getCode())) {
            // SUserVo sUserVo = getSendUserVo();
            // if (Objects.nonNull(sUserVo)) {
            //     // 给钱昱帆发送确认单
            //     approvalFlowService.sendAeNotify(aeQuarterlyTable.getTenantId(), aeQuarterlyTable.getId(),
            //             aeQuarterlyTable.getAeQuarterlyExcuteCode(), aeQuarterlyCode,
            //             ApprovalEnum.AE_DEFAULT_COMMISSION, false, sUserVo.getUserId(), sUserVo.getUsername(), AeCommonEnum.IS_BOOS.getCode());
            // }
            // 执行单改为已结算
            batchUpdateSettleStatus(excuteIds, CommonSettleStatusEnum.SETTLED.code());
            //插入发放时间
            aeQuarterlyTable.setIssueDate(new Date());
        }
        // 作废
        if (aeQuarterlyType.equals(AeQuarterlyTypeEnum.YZF_CONTRACT.getCode())) {
            // 执行单改为未结算
            batchUpdateSettleStatus(excuteIds, CommonSettleStatusEnum.UNSETTLED.code());
            aeRoyaltiesList.forEach(x -> {
                x.setIsDelete(AeCommonEnum.DATA_IS_DELETE.getCode());
                x.setIsInvalid(AeCommonEnum.IS_INVALID.getCode());
                x.ignore();
            });
            this.aeRoyaltiesService.updateBatchById(aeRoyaltiesList);
        }
        // 修改季度单状态
        if (Objects.isNull(aeRoyaltiesExportDTO.getType())) {
            aeQuarterlyTable.setStatus(aeQuarterlyType);
            aeQuarterlyTable.ignore();
            aeQuarterlyTableMapper.updateById(aeQuarterlyTable);
        }
    }

    @Override
    public SUserVo getSendUserVo() {
        Map<String, SUserVo> sUserVoMap =
                Objects.requireNonNull(privilegeClient.getUserIdsByName(Collections.singletonList(sendName))).getObj();
        return sUserVoMap.get(sendName);
    }

    @Override
    public List<String> getAeQuarterlyCode() {
        List<AeQuarterlyTable> list = aeQuarterlyTableMapper.selectList(Wrappers.lambdaQuery(AeQuarterlyTable.class)
                .eq(AeQuarterlyTable::getIsDelete, AeCommonEnum.DATA_NOT_DELETE));
        return list.stream().filter(CommonUtil.distinctByKey(AeQuarterlyTable::getAeQuarterlyCode))
                .map(AeQuarterlyTable::getAeQuarterlyCode).collect(Collectors.toList());
    }

    @Override
    public List<String> getMonths() {
        return aeQuarterlyTableMapper.getMonths();
    }

    @Override
    public AeQuarterlyBoxList getAeQuarterlyBoxList() {
        List<AeRoyalties> aeRoyalties = aeRoyaltiesMapper.selectList(Wrappers.lambdaQuery(AeRoyalties.class).eq(AeRoyalties::getIsDelete, AeCommonEnum.DATA_NOT_DELETE));
        List<String> executorNames = aeRoyalties.stream().map(AeRoyalties::getExcutorName).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        List<String> depPrincipalNames = aeRoyalties.stream().map(AeRoyalties::getDepPrincipalName).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        AeQuarterlyBoxList aeQuarterlyBoxList = new AeQuarterlyBoxList();
        aeQuarterlyBoxList.setAeExecutorNames(executorNames);
        aeQuarterlyBoxList.setAeDepPrincipalNames(depPrincipalNames);
        return aeQuarterlyBoxList;
    }

    /**
     * 批量更新执行单提成结算状态
     *
     * @param excuteIds
     * @param commissionSettleStatus
     */
    private void batchUpdateSettleStatus(List<Long> excuteIds, Integer commissionSettleStatus) {
        if (CollectionUtils.isEmpty(excuteIds)) {
            return;
        }
        // 执行单改为未结算
        contractExcutionOrderService.batchUpdateSettleStatus(excuteIds, commissionSettleStatus);
    }
}
